home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Library / +ORC / Orc pac 9D / CIVETTA.TXT next >
Text File  |  2000-05-25  |  32KB  |  673 lines

  1.               NO MORE annoying anti SOFT-ICE tricks or
  2.               how to improve SOFT-ICE!
  3.  
  4.    intro
  5.  
  6.       today's best EXE protectors contain code to prevent debugging with
  7.    SOFT-ICE, which is the best debugger among the ones i came across so
  8.    far. following protectors are known to me to defeat SOFT-ICE:
  9.  
  10.       EEXE (Encrypt Exe found in FZC.EXE)
  11.       HACKSTOP (found in WWPACK.EXE)
  12.       PROTECT! (found in various files)
  13.       GUARDIAN ANGEL (found in some versions of HWINFO.EXE)
  14.       EXELITE (a Polish exe compressor)
  15.       the one written by PREDATOR 666 (found in DCA.EXE v1.4)
  16.       the one used by Martin Malík (found in HWINFO.EXE v3.05 and up)
  17.       DS-CRP by Dark Stalker (hi!)
  18.       SECURE v0.19 by the authors of WWPACK
  19.       ALEC v1.5 (the very best protector :-) by Random
  20.       and a few others i don't remember right now...
  21.  
  22.    the problems
  23.  
  24.       SOFT-ICE can be detected/halted/crashed in many ways, here's a short
  25.    list of them (some of them only makes single stepping harder but not
  26.    impossible). i also included a short note on the effects for each version
  27.    of SOFT-ICE:
  28.                  :-( this trick works,
  29.                  :-) it causes no problems
  30.  
  31.       1. by the use of the INT3 interface provided by SOFT-ICE one can
  32.          check for the presence of SOFT-ICE and then have it execute various
  33.          commands, e.g. HBOOT (see HackStop). the loader part of SOFT-ICE
  34.          also leaves some traces in the low DOS memory, so one can find out
  35.          the entrance values of the INT3 interface even if they were changed
  36.          (see HMVS - a heuristic macro virus scanner - by J. Valky and
  37.          L. Vrtik that uses SECURE v0.19). the Windows versions can also be
  38.          detected by the following code (thanks to Dark Stalker and ACP :-):
  39.  
  40.            mov ebp,"BCHK"
  41.            mov ax,4
  42.            int 3
  43.            cmp ax,4
  44.            jne winice_installed
  45.  
  46.          it seems that BoundsChecker talks to SOFT-ICE via an interface very
  47.          similar to the one between LDR.EXE and SOFT-ICE (although it's
  48.          completely undocumented, as far as i know...)
  49.  
  50.          DOS: :-(
  51.          W31: :-( (but the SECURE method is :-)
  52.          W95: not tested yet (probably same as W31)
  53.          WNT: not tested yet (probably same as W31)
  54.  
  55.       2. by checking for various devices SOFT-ICE installs ("CVDEBUG",
  56.          "NU-MEGA", "SOFTICE1") and searching the part of the code SOFT-ICE
  57.          leaves in the low DOS memory for some patterns (e.g. "CVDEBUG",
  58.          "NU-MEGA", "SEGMAP", "S-ICE" (the latter coming from the filename),
  59.          and any instruction sequence that's left there) one can detect the
  60.          presence of SOFT-ICE. the Window$ versions provide a VXD entry point
  61.          that can be get by:
  62.  
  63.            mov ax,01684h
  64.            mov bx,0202h ; VXD ID for Winice, check out Ralf Brown's INTLIST
  65.            xor di,di
  66.            mov es,di
  67.            int 2fh
  68.            mov ax,es
  69.            add di,ax
  70.            cmp di,0
  71.            jne winice_is_installed
  72.  
  73.          the Window$ versions can also be detected by calling the "debugger
  74.          install check" function of the Window$ debug kernel (int 42/ax=0041),
  75.          for more details see Ralf Brown's INTLIST.
  76.  
  77.          see HWINFO.EXE and DS-CRP.COM for an extensive application of these
  78.          checks...
  79.  
  80.          DOS: :-(
  81.          W31: :-) but the VXD entry point check is :-(
  82.          W95: not tested yet (probably same as W31)
  83.          WNT: not tested yet (probably same as W31)
  84.  
  85.       3. by the use of the undocumented ICEBP/INT01 instruction (opcode 0xF1):
  86.          SOFT-ICE gives a short beep before the execution of this instruction
  87.          (it will be reflected back to the V86 mode handler, thus at least
  88.          the intended handler will get it) which can be VERY annoying (and
  89.          make the execution VERY slow), see EEXE for an application of this.
  90.  
  91.          DOS: :-(
  92.          W31: :-)
  93.          W95: not tested yet (probably same as W31)
  94.          WNT: not tested yet (probably same as W31)
  95.  
  96.       4. by using the TRAP flag, one can use the single stepping feature to
  97.          call a protection routine (e.g. a decryptor). the problem is, that
  98.          during single stepping SOFT-ICE clears the TRAP flag for the V86 task
  99.          and will neither execute nor step into the INT01 handler of the
  100.          V86 task. many schemes use this trick.
  101.  
  102.          DOS: :-(
  103.          W31: :-(
  104.          W95: not tested yet (probably same as W31)
  105.          WNT: not tested yet (probably same as W31)
  106.  
  107.       5. by the use of the debug (DRx) and control (CRx) registers:
  108.          accessing these registers in V86 mode leads to a General Protection
  109.          Fault (INT0D), which SOFT-ICE doesn't handle correctly (it's normally
  110.          used for emulating instructions that access the interrupt flag, the
  111.          debug registers, the control registers, etc.). the protected mode
  112.          handler emulates instructions that access these registers by
  113.          executing them, however it doesn't make note about this for itself,
  114.          i.e. whenever a debug fault is triggered SOFT-ICE will think that
  115.          it must pop up and won't reflect back this exception to the V86 mode
  116.          handler (that's waiting for it in vain). for a working example see
  117.          GUARDIAN ANGEL. furthermore, accessing DR4/5 and CR1 will halt
  118.          SOFT-ICE with a General Protection Violation error message, which is
  119.          of course quite disturbing if it's used many times in the program...
  120.  
  121.          and best of all by accessing CR4 SOFT-ICE simply crashes since
  122.          there's no emulation code for this kind of instructions (there's a
  123.          jump table that tells SOFT-ICE which routine to use to handle these
  124.          instructions and the table ends with CR3...). this method was first
  125.          used by Random in his ALEC.EXE v1.4 :-)
  126.  
  127.          another sad fact is that the emulation in SOFT-ICE is not complete:
  128.          it ALWAYS uses eax no matter what the original instruction was...
  129.  
  130.          e.g. mov dr0,ebx will load dr0 from eax!
  131.               mov ecx,dr0 will load eax from dr0!
  132.  
  133.          i guess it's needless to say how easy it is to detect this behavior...
  134.  
  135.          a sidenote for protection writers: other memory managers that run
  136.          DOS in V86 mode may or may not handle these instructions correctly,
  137.          so the use of this trick is highly discouraged.
  138.  
  139.          DOS: :-(
  140.          W31: :-(
  141.          W95: not tested yet (probably same as W31)
  142.          WNT: not tested yet (probably same as W31)
  143.  
  144.       6. by the use of INT08, which is the timer interrupt in real mode DOS,
  145.          and the Double Fault Exception in protected mode. the protected mode
  146.          handler checks whether it was entered from V86 mode or not, and in
  147.          the first case it reflects back this interrupt to the V86 mode
  148.          handler. however, one can't single step into it.
  149.  
  150.          DOS: :-(
  151.          W31: :-)
  152.          W95: not tested yet (probably same as W31)
  153.          WNT: not tested yet (probably same as W31)
  154.  
  155.       7. by the use of the INT07 interrupt (this is the Coprocessor Not
  156.          Available Exception):
  157.          instead of reflecting back this interrupt to the V86 mode handler,
  158.          SOFT-ICE tries to skip the offending coprocessor instruction (it
  159.          checks for some opcodes). it seems the Nu-Mega folks never thought
  160.          it would be called directly... for a real life application get some
  161.          programs written (and protected) by Predator 666.
  162.  
  163.          DOS: :-(
  164.          W31: :-)
  165.          W95: not tested yet (probably same as W31)
  166.          WNT: not tested yet (probably same as W31)
  167.  
  168.       8. by the use of the Invalid Opcode Exception (INT06):
  169.          SOFT-ICE tries to emulate some instructions (e.g. LOADALL), and then
  170.          reflects back this exception to the V86 mode handler. however,
  171.          certain opcodes aren't recognized and will give you an error message
  172.          (i.e. execution will be interrupted, if the protection scheme uses
  173.          this trick).
  174.  
  175.          DOS: :-(
  176.          W31: :-(
  177.          W95: not tested yet (probably same as W31)
  178.          WNT: not tested yet (probably same as W31)
  179.  
  180.       9. by using direct INTxx calls that are triggered by hardware
  181.          interrupts (e.g. INT08-INT0F, INT70-INT77, if the vectors in the PIC
  182.          are not reprogrammed), one will not be able to single step into the
  183.          interrupt handler. in fact, SOFT-ICE will even execute the next
  184.          instruction and just then stop (if the next instruction is also an
  185.          INTxx call of this type then it will be stepped over as well, and so
  186.          on). so far, i know of no protection scheme that uses this trick,
  187.          but i guess i've just given out a good idea :-).
  188.  
  189.          DOS: :-(
  190.          W31: :-)
  191.          W95: not tested yet (probably same as W31)
  192.          WNT: not tested yet (probably same as W31)
  193.  
  194.       A. by reloading IDTR one can change the base and size of the interrupt
  195.          table in real mode as well. however, SOFT-ICE will not emulate this
  196.          instruction (it causes a General Protection Fault in V86 mode) thus
  197.          a protection using LIDT won't run. the only problem is that memory
  198.          managers don't like it very much, so probably we won't see it in a
  199.          real life protection scheme, but one never knows :-).
  200.  
  201.          DOS: :-(
  202.          W31: :-(
  203.          W95: not tested yet (probably same as W31)
  204.          WNT: not tested yet (probably same as W31)
  205.  
  206.       B. sometimes one has to call an interrupt directly (GENINT xx), e.g. to
  207.          dump a memory range to disk by using one's memory resident dumper
  208.          (you know what i mean :-) and it's very annoying that SOFT-ICE
  209.          doesn't stop after the interrupt call but executes the program
  210.          being debugged (thus one has to set a breakpoint for a moment at the
  211.          current CS:IP which will result in an unwanted 0xCC byte in the dump,
  212.          if all debug registers are already used).
  213.  
  214.          DOS: :-(
  215.          W31: :-(
  216.          W95: not tested yet (probably same as W31)
  217.          WNT: not tested yet (probably same as W31)
  218.  
  219.       C. in plain DOS INT3 and INT1 are handled by the same routine (which is
  220.          a simple IRET). however, SOFT-ICE changes the INT3 handler of the
  221.          V86 task to another IRET which can be detected by comparing its
  222.          offset to the one of the INT1 handler. see HWINFO.EXE for
  223.          an application
  224.  
  225.          DOS: :-(
  226.          W31: :-)
  227.          W95: not tested yet (probably same as W31)
  228.          WNT: not tested yet (probably same as W31)
  229.  
  230.    the solutions
  231.  
  232.       in the following part you'll be presented with some ideas about the
  233.    solution for the problems described above (the file offsets refer to the
  234.    DOS version v2.80, but the ideas should work for other versions, as well.
  235.    the easiest way to apply the patches is using Hacker's View which can
  236.    be found in HIEW531.ZIP).
  237.  
  238.       one general problem is that SOFT-ICE (at least the DOS version) doesn't
  239.    reprogram the hardware interrupt vectors, and this makes life (and the
  240.    interrupt handlers) a bit more complex. the IDT that SOFT-ICE uses has
  241.    entries that point to the following type of code:
  242.  
  243.    push xx
  244.    jmp handler_xx
  245.  
  246.    where xx goes from 0x00 to 0xFF. in v2.80 this code begins at offset
  247.    0x4534. the Win31 version has a very similar code beginning at offset
  248.    0x14167 in v1.52:
  249.  
  250.    push d,[offset_xx]
  251.    jmp handler_xx
  252.  
  253.       if you want to understand the patches that follow right below, you
  254.    should study the interrupt handlers (and you should also have a good
  255.    understanding of protected mode). however, some problems cannot be solved
  256.    without understanding the internal flags of SOFT-ICE, and this requires a
  257.    complete disassembly of it, which is a quite hard task i can tell.
  258.  
  259.       anyway, sooner or later it will be done, and then we'll have the
  260.    ultimate debugging/cracking tool in our hands 'cos we'll be able to put in
  261.    some missing functions, e.g. emulation of FlatRealMode, tracing INT1, PIC
  262.    reprogramming, prefetch queue emulation, dumping a memory range to disk,
  263.    etc. until then, enjoy the poor man's patches...
  264.  
  265.       1. some exe protections mentioned earlier are based upon the INT3
  266.          interface of SOFT-ICE (see Ralf Brown's Interrupt List for details).
  267.          this interface is activated when the protected mode INT3 handler of
  268.          SOFT-ICE encounters the magic values in SI and DI. that is, when you
  269.          try to trace through an INT3 call, SOFT-ICE will regain control,
  270.          check for the magic values, and in case they are not found, it will
  271.          reflect back this interrupt to the V86 mode INT3 handler (which it
  272.          was supposed to do anyway). if it finds the magic values, then
  273.          it'll execute the command given in AX (and DS:DX). all of these
  274.          checks happen invisibly to the hacker, so there seems to be no
  275.          solution to defeat this kind of protection (well, there's a slow way
  276.          if you step through every instruction and before the "guilty" INT3
  277.          call you change one or two registers).
  278.  
  279.          however, there's a simple solution: change the magic values SOFT-ICE
  280.          is looking for and this will defeat those protectors based upon the
  281.          INT3 interface. however, it's easier said than done because both
  282.          SOFT-ICE (and WIN-ICE) itself and (W)LDR.EXE use this interface for
  283.          some kind of intra/inter process communication. so every reference
  284.          to the magic values will have to be changed!
  285.  
  286.          to keep the story short here's what i've come up with:
  287.          browsing a few minutes in Hacker's View (another important tool ;-)
  288.          i found the places where those changes had to be done. in order to
  289.          avoid changes where those magic values occur by chance, i wrote an
  290.          MSUB script to change whole instructions (they represent enough
  291.          context). the amount of necessary changes would have forced me to
  292.          use some search&replace utility, anyway. MSUB.EXE can be found in
  293.          MSUB13.ZIP (use an ftp search engine to find it).
  294.  
  295.          the scripts
  296.  
  297.          SICE-VAL.MS: you should specify the old and new magic values in it
  298.                       (note that numbers are decimal!)
  299.  
  300.          SICE2NEW.MS: it will replace the old magic values with the new ones.
  301.                       there are almost 2^32 possible values, only that value
  302.                       is forbidden for SI that equals to the version of
  303.                       SOFT-ICE (for v2.80 it is \128\2, i.e. 0x0280). before
  304.                       SOFT-ICE installs itself, it checks for its presence by
  305.                       using an undocumented function of its INT3 interface by
  306.                       setting AH to 0 or 1. on return SI will be loaded with
  307.                       the version number or left unmodified if it's not
  308.                       installed yet, that's why the version number must differ
  309.                       from the preloaded value of SI.
  310.  
  311.          example usage
  312.  
  313.                   MSUB.EXE SICE2NEW.MS S-ICE.EXE LDR.EXE
  314.  
  315.          if you're fed up with the shareware delay built into MSUB.EXE,
  316.          here's how you can get rid of it (thanks to a friend of mine ;-)
  317.  
  318.          patch MSUB.EXE v1.3 (113,152 bytes long) as follows:
  319.  
  320.          offset    old new
  321.          00002307: ??  EB
  322.          00002308: ??  03
  323.          0000C0DF: 77  EB
  324.  
  325.          the protection that SECURE uses is quite clever 'cos it checks the
  326.          first 16 kBytes for the instruction sequence of
  327.  
  328.          mov si,SI_MAGIC
  329.          mov di,DI_MAGIC
  330.  
  331.          they're encoded as 0BEh,x,y,0BFh,u,v where x,y,u and v are the magic
  332.          values. when it finds 0BEh and 0BFh separated by two bytes from each
  333.          other then it calls INT3 with the supposed magic values (the INT3
  334.          handler is a simple IRET, so no problem should arise if SOFT-ICE is
  335.          not installed). and guess what happens when SECURE finds the traces
  336.          of the loader part of SOFT-ICE in that low memory area...
  337.  
  338.          the only solution that would defeat this kind of protection is to
  339.          change the instructions that load SI and DI before the INT3 calls
  340.          (unfortunately you can't avoid those calls since SOFT-ICE has to
  341.          check for its presence and do other things). for obvious reasons
  342.          (i guess one of the previous versions of this file gave the SECURE
  343.          authors the idea...) i won't give you tips on how to do it, i hope
  344.          you're smart enough to do it yourselves.
  345.  
  346.          the only limit is that you have 6 bytes of space to load both SI and
  347.          DI (i checked that whenever SOFT-ICE uses the INT3 interface it loads
  348.          SI and DI by two consecutive instructions, i.e. you can use the MSUB
  349.          scripts to search for and replace them). another method could be to
  350.          change the HBOOT command to something else (by MSUB of course),
  351.          however other dangerous commands could be still issued...
  352.  
  353.          the BoundsChecker interface can be modified in the same way we did
  354.          it with the rest of the INT3 interface: simply modify the value that
  355.          is expected in ebp (but BoundsChecker must be changed as well!).
  356.          look for the string "KHCB" to find the appropriate place.
  357.          the following file offsets are valid for WINICE for Win 3.1 v1.52:
  358.  
  359.          offset    old new
  360.          000130C7: 'K' ?
  361.          000130C8: 'H' ?
  362.          000130C9: 'C' ?
  363.          000130CA: 'B' ?
  364.  
  365.          for WINICE for Win95 v3.0:
  366.  
  367.          offset    old new
  368.          00016FDD: 'K' ?
  369.          00016FDE: 'H' ?
  370.          00016FDF: 'C' ?
  371.          00016FE0: 'B' ?
  372.  
  373.          and for WINICE for Win95 v3.01:
  374.  
  375.          offset    old new
  376.          000243F0: 'K' ?
  377.          000243F1: 'H' ?
  378.          000243F2: 'C' ?
  379.          000243F3: 'B' ?
  380.  
  381.       2. the device names can be changed to anything you want, look at the
  382.          beginning of S-ICE.EXE. the real problem is when the protection
  383.          checks for instruction sequences. my only advice is that step through
  384.          the protection and see which part of the code is checked for, then
  385.          try to modify it in S-ICE.EXE (or disassemble, modify and then
  386.          recompile the whole executable, but that's not gonna happen for
  387.          a long time, i guess... :-).
  388.  
  389.          to defeat the int41 check, you have to change both the return value
  390.          of the real and protected mode handlers in WINICE and the value that
  391.          is checked for in KRNL386.EXE, VMM32.VXD, EMM386.EXE, IFSHLP.SYS and
  392.          NET.EXE. all these changes are necessary otherwise some WINICE
  393.          commands (HWND, TASK) won't work 'cos apparently they rely on some
  394.          Window$ functions which are available only in the debug kernel (and
  395.          during startup these programs/drivers do this int41 check which will
  396.          fail if you don't change the values they're expecting, as well).
  397.  
  398.          there're five places in WINICE that have to be patched (one is a cmp,
  399.          the other four are mov's) and one in each one of the rest. sorry,
  400.          that i don't provide you with detailed offsets, but there're too many
  401.          versions/combinations of both WINICE and Win31/Win95... note, that
  402.          after these changes other programs that want to use debug kernel
  403.          functions will fail :-)
  404.  
  405.          and now let's talk about the VXD entry point check. the ID is stored
  406.          at file offset 0x7821E in WINICE for Win95 v3.01 (to find it in
  407.          other versions as well just look for "SICE   ", and the ID will be
  408.          a few bytes before this text).
  409.  
  410.          so to change the ID just overwrite it there. however, it's not
  411.          enough since some companion programs also test for WINICE by trying
  412.          to get the VXD entry point, i.e. they have to be modified as well.
  413.          they're DLOG.EXE and WLDR.EXE, and search for int2F (opcode: 0xCD
  414.          0x2F) to get to the right place... :-)
  415.  
  416.          anyway, for the versions that come with WINICE for Win95 v3.0,
  417.          the file offsets of the ID are 0x625/6 and 0x68B9/A respectively.
  418.  
  419.       3. what we have to do is simply skip the unnecessary parts in the
  420.          handler (the beeps) and simulate the instruction as it would have
  421.          been a direct INT 01 call (opcode: 0xCD 0x01). this way one will not
  422.          only get rid of the beeps but be able to trace into the handler as
  423.          well (and we'll have some space to put some extra code in when we'll
  424.          need it :-).
  425.  
  426.          offset    old new
  427.          00001DD5: 50  EB
  428.          00001DD6: 51  60
  429.  
  430.       4. [this part is being worked on]
  431.  
  432.  
  433.       5. there are two possible solutions: we either disable the DRx emulation
  434.          feature of SOFT-ICE (this is quite easy to do) or correct it (this is
  435.          really hard to do). SOFT-ICE emulates each instruction by executing
  436.          a function whose offset is looked up in a table. each function ends
  437.          in the same way: IP of the V86 task is incremented by the appropriate
  438.          amount of bytes. so to disable emulation we'll change the pointers
  439.          in that table to the common end of the functions, this way these
  440.          instructions will essentially be handled as NOPs. i don't know
  441.          whether it's worth to do it or not, since this modification can be
  442.          detected by simply loading one of the debug registers and then
  443.          checking whether it's really been modified or not. a more elegant
  444.          solution would be to reserve a few bytes in the data segment of
  445.          SOFT-ICE for storing the values of these registers and emulate the
  446.          instructions (or at least their loading). anyone out there willing
  447.          to do that?
  448.  
  449.          anyway, here's how to do the patch: the table itself is at file
  450.          offset 0x1F1DD and it has 12 words in it pointing to the
  451.          emulation code of the following instructions:
  452.  
  453.              mov eax,dr0 and mov dr0,eax
  454.              mov eax,dr1 and mov dr1,eax
  455.              mov eax,dr2 and mov dr2,eax
  456.              mov eax,dr3 and mov dr3,eax
  457.              mov eax,dr4 and mov dr4,eax
  458.              mov eax,dr5 and mov dr5,eax
  459.              mov eax,dr6 and mov dr6,eax
  460.              mov eax,dr7 and mov dr7,eax
  461.              mov eax,cr0 and mov cr0,eax
  462.              mov eax,cr1 and mov cr1,eax
  463.              mov eax,cr2 and mov cr2,eax
  464.              mov eax,cr3 and mov cr3,eax
  465.  
  466.          note that there's no offset for emulating CR4...
  467.  
  468.          the offset of the common exit point (i.e. the new value you may want
  469.          to set these pointers to) is 0x175A (this is NOT a file offset...).
  470.  
  471.          these patches still don't cure the problem with CR4. if you decided
  472.          to get rid of the emulation entirely (including CR4) then you can
  473.          do it much easier:
  474.  
  475.          offset    old new
  476.          00002E7E: 03  0A
  477.          00002E7F: 00  01
  478.  
  479.       6. i'll give you a general solution in section 8 since INT08 is just a
  480.          a subset of the hardware interrupts which are discussed there.
  481.  
  482.       7. this problem can be solved quite easily: we replace the original
  483.          protected mode handler with the one that serves all not_IRQ_related
  484.          interrupts (and whose only task is to reflect them back to the
  485.          V86 mode handler).
  486.  
  487.          offset    old new
  488.          0000455A: B6  14
  489.          0000455B: DF  D6
  490.  
  491.       8. what we have to do is to skip the call that prints the error message
  492.          and simply reflect this interrupt back to the V86 mode handler.
  493.          note that your buggy programs won't cause SOFT-ICE to pop up after
  494.          this patch :-) (however, you'll be able to break in and see what
  495.          went wrong).
  496.  
  497.          offset    old new
  498.          00002447: A9  C3
  499.  
  500.       9. now we'll make use of the extra space we made in the original INT01
  501.          handler. we have to check whether the interrupt was triggered by a
  502.          hardware IRQ or not. this can be done by the following routine:
  503.  
  504.          push eax          ; save the registers that will be modified
  505.          pushf             ; the order of PUSHs is important!
  506.          mov al,0Bh        ; we'll read in the in-service registers
  507.          out 20h,al        ; master PIC
  508.          out 0A0h,al       ; slave PIC
  509.                            ; there might be needed a short delay here
  510.                            ; however, on my machine it isn't :-)
  511.          in al,20h         ; read INTs being serviced by master PIC
  512.          mov ah,al         ; save for later test
  513.          in al,0A0h        ; read INTs being serviced by slave PIC
  514.          test ax,0FFFFh    ; was it a hardware int?
  515.          jnz original      ;
  516.          popf              ; restore flags
  517.          pop eax           ; the general handler doesn't expect it
  518.          jmp offset 1B70h  ; this has to be the general handler (this offset
  519.                            ; is valid in v2.80)
  520.          original:
  521.          mov ax,8          ; the first two instructions of the original handler
  522.          popf              ; were push eax, mov ax,8, thus we won't pop eax
  523.          jmp offset 1A77h  ; this has to be the original handler's offset
  524.                            ; plus 5 bytes (the length of push eax, mov ax,8)
  525.  
  526.          and at the beginning of the original handler (offset 0x1A72) we put:
  527.          jmp offset 1DD7h  ; and since it's only 3 bytes long,
  528.                            ; we get 2 spare bytes :-)
  529.  
  530.          the binary patches follow:
  531.  
  532.          offset    old new
  533.          00001A72: 66  E9
  534.          00001A73: 50  62
  535.          00001A74: B8  03
  536.  
  537.          00001DD5: 50  EB
  538.          00001DD6: 51  60
  539.          00001DD7: B9  66
  540.          00001DD8: 03  50
  541.          00001DD9: 00  9C
  542.          00001DDA: B0  B0
  543.          00001DDB: 03  0B
  544.          00001DDC: E6  E6
  545.          00001DDD: 61  20
  546.          00001DDE: 51  E6
  547.          00001DDF: 33  A0
  548.          00001DE0: C9  E4
  549.          00001DE1: E2  20
  550.          00001DE2: FE  8A
  551.          00001DE3: E2  E0
  552.          00001DE4: FE  E4
  553.          00001DE5: E2  A0
  554.          00001DE6: FE  A9
  555.          00001DE7: E2  FF
  556.          00001DE8: FE  FF
  557.          00001DE9: E2  B8
  558.          00001DEA: FE  08
  559.          00001DEB: E2  00
  560.          00001DEC: FE  75
  561.          00001DED: E2  06
  562.          00001DEE: FE  9D
  563.          00001DEF: E2  66
  564.          00001DF0: FE  58
  565.          00001DF1: E2  E9
  566.          00001DF2: FE  7C
  567.          00001DF3: E2  FD
  568.          00001DF4: FE  9D
  569.          00001DF5: E2  E9
  570.          00001DF6: FE  7F
  571.          00001DF7: E2  FC
  572.  
  573.       A. to solve this problem we should do a complete disassembly of SOFT-ICE
  574.          since we have to keep track of the base and size of the V86 mode
  575.          interrupt table, and this requires too many changes to be worth to do
  576.          it with simple byte patches.
  577.  
  578.       B. a somewhat lame (but it's more than nothing) solution is the
  579.          following: we chain in a P RET command after GENINT by patching
  580.          the jump at the end of the GENINT handler to the beginning of P RET.
  581.          after executing GENINT we'll land at the IRET of our handler and
  582.          a further P or T will take us back to the original instruction we
  583.          were at. i said it was somewhat lame... but it works :-)
  584.  
  585.          offset    old new
  586.          000118BF: BC  00
  587.          000118C0: E0  C7
  588.  
  589.       C. before executing anything call up SOFT-ICE and change the offset of
  590.          the V86 mode INT3 handler to the one of the INT1 handler.
  591.  
  592.       D. !!! SURPRISE !!!
  593.  
  594.          while you're in WINICE for Win95 v3.0 or 3.01 type in the following
  595.          command: "ver ice" and see what you get... however, note that due
  596.          to a bug (or feature?) you can use only once this command during
  597.          a session, you have to restart WINICE to be able to get the
  598.          message again.
  599.  
  600.          and while we're at undocumented features, try out "ver ?" as well.
  601.          in the next release, i'll try to write a detailed description
  602.          of the new commands (not that if it were that hard to find out...)
  603.  
  604.    unsolved mysteries :-)
  605.  
  606.       1. even the Nu-Mega docs tell about a problem when SOFT-ICE for DOS is
  607.          loaded from the command line: if HIMEM.SYS is installed the machine
  608.          simply reboots. i tracked down the problem and found out that the
  609.          processor resets itself because of a triple fault. it happens so:
  610.  
  611.          after preparing the IDT and GDT (and loading IDTR and GDTR), paging
  612.          will be enabled in CR0, and then DS and ES will be loaded a
  613.          descriptor offset of 8. however, both this descriptor and the IDT
  614.          seem to be invalid, and this leads to a triple fault. unfortunately,
  615.          i couldn't find out what goes wrong during the setup of IDT and GDT,
  616.          perhaps someone else out there will do the dirty job :-)... and maybe
  617.          Nu-Mega will award you with a free, legal version :-)).
  618.  
  619.       2. on a Cyrix 486DLC-40 system (both with and without a coproc) SOFT-ICE
  620.          gets a Page Fault and halts if the processor is running at 40 MHz,
  621.          but works fine at 33 MHz. the Page Fault seems to happen while the
  622.          code window is being put out (i.e. during the execution of the wc
  623.          command). this is nonsense! so far, no solution... and yes, it's
  624.          another dirty job...
  625.  
  626.    P.S. for everyone
  627.  
  628.          perhaps there's someone out there who didn't know it so far...
  629.          WINICE can be used without Window$ (and you'll be able to debug
  630.          programs that use some DOS extender, if it can make use of DPMI, but
  631.          that's the case with the most popular ones, e.g. DOS4GW or PMODE/W)!
  632.          the trick is that you have to make a 'crippled' version of Window$,
  633.          i.e. make Window$ start without its GUI. a complete description of
  634.          this can be found at the following URL:
  635.  
  636.                 http://www.fys.ruu.nl/~faber/Windows_No_GUI
  637.  
  638.          after creating this GUI-less Window$ all you have to do is to start
  639.          WINICE (beware, your normal Window$ shouldn't be on your PATH!) and
  640.          voila, you'll be in a DOS session (i hope that you could find it out
  641.          yourself that you had to start COMMAND.COM as your KRNL386.EXE...)
  642.          with WINICE being able to pop up whenever you need it (of course, for
  643.          native Window$ programs you'll need a full Window$).
  644.  
  645.          and if we're at Window$ here's another trick: if you don't want to
  646.          see the logo being shown every time you start Window$, either start
  647.          WIN.COM with a command line paramater of ':' i.e.
  648.  
  649.                 WIN.COM :
  650.  
  651.          or (as the above method doesn't work with our GUIless version since
  652.          WINICE doesn't seem to pass any parameters or you are too lazy to
  653.          type in every time 2 more characters :-) look for the string 'LOGO'
  654.          in WIN.COM and change it to something else (it's enough to change
  655.          only one bit). note, that the WIN.COM of Window$ for Workgroups
  656.          doesn't like this patch...
  657.  
  658.    P.S. for protection writers
  659.  
  660.          i know that some of the above modifications can be defeated (i could
  661.          do it myself) however i won't make your life easier... i hope you
  662.          understand why :-)
  663.  
  664. Courtesy of FraVia's page of reverse engineering, Mar 1997
  665.  
  666.     __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/
  667.  
  668.                    FraVia's page of reverse engineering:
  669.          http://ourworld.compuserve.com/homepages/fravia (backbone)
  670.                 http://www.geocities.com/Athens/5513 (main)
  671.                http://www.mygale.org/01/fravia (escape route)
  672.     __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/ __/
  673.